import asyncio
import os
import sys

import click
import uvicorn
from fastapi_utils.tasks import repeat_every
from py_eureka_client import eureka_client
from re_common.baselibrary.utils.baseip import BaseIp

from app_main import sets, app, p_db


# 周期性任务
@app.on_event("startup")
@repeat_every(seconds=20, raise_exceptions=True)
async def periodic():
    if not isinstance(app.state.port, int):
        return False
    ip_port = app.state.ip + ":" + str(app.state.port)
    version = sets.VERSION
    tags = app.state.tags
    sql = "insert into server_address(ip_port,count,tags,version) values ('%s',1,'%s','%s') on duplicate key update count = count +1,tags = '%s',version = '%s'" % (
        ip_port, tags, version, tags, version)

    pool = app.state.pool
    async with pool.acquire() as conn:
        async with conn.cursor() as cur:
            await cur.execute(sql)
            await conn.commit()


def setEureka(server_port, app_name):
    server_host = str(BaseIp().GetLocalIPByPrefix("192.168"))
    server_port = server_port
    eureka_client.init(eureka_server="http://192.168.31.165:19000/eureka/",
                       app_name=app_name,
                       # 当前组件的主机名，可选参数，如果不填写会自动计算一个，如果服务和 eureka 服务器部署在同一台机器，请必须填写，否则会计算出 127.0.0.1
                       instance_host=server_host,
                       instance_port=server_port,
                       # 调用其他服务时的高可用策略，可选，默认为随机
                       ha_strategy=eureka_client.HA_STRATEGY_RANDOM)


@click.command()
@click.option('--port', default=8001, help='set port')
@click.option('--tags', default="main", help='set test')
@click.option('--app_name', default='fastapi-cjserver',
              type=click.Choice(['fastapi-cjserver', 'fastapi-cjserver-test']), help='set app_name')
def start(port, tags, app_name):
    """
    :param port: 传入端口号，默认为8001
    :param tags: main为调试正确的服务，test为调试服务
    :param app_name:
    :return:
    """
    try:
        pid = os.getpid()
        p_db.set(str(pid) + "_port", port)
        p_db.set(str(pid) + "_tags", tags)
        setEureka(port, app_name)
    except Exception as e:
        print(e)
    # ml = "uvicorn main:app --reload --host=0.0.0.0 --port={}".format(port)
    # os.system(ml)
    # loop = asyncio.ProactorEventLoop()
    # if sys.platform == 'win32':
    #     # asyncio 的事件循环有两种不同的实现：SelectorEventLoop和 ProactorEventLoop，它们的父类是AbstractEventLoop
    #     # SelectorEventLoop
    #
    #     selector = selectors.SelectSelector()
    #     loop = asyncio.SelectorEventLoop(selector)
    #     # 这个是asyncio默认使用的Event Loop实现，支持unix和windows平台
    #     # ProactorEventLoop
    #     # 这个是Windows平台专有的实现
    #     loop = asyncio.ProactorEventLoop()
    #     # asyncio.set_event_loop(loop)
    uvicorn.run(app='main:app', host='0.0.0.0', port=port, reload=True)


if __name__ == '__main__':
    start()

# gunicorn main:app -b 0.0.0.0:8000 -w 4 -k uvicorn.workers.UvicornH11Worker --daemon
# 启动命令
# (端口号，默认不输入参数为8000) (tags,默认为main,测试需更改为test，正常使用为main)   (app_name，默认fastapi-cjserver)
# python main.py --port 8001 --tags main --app_name fastapi-cjserver
